home *** CD-ROM | disk | FTP | other *** search
/ Aminet 25 / Aminet 25 (1998)(GTI - Schatztruhe)[!][Jun 1998].iso / Aminet / game / shoot / ADoom_src_1_2.lha / ADoom_src / r_things.c < prev    next >
C/C++ Source or Header  |  1998-03-01  |  22KB  |  1,039 lines

  1. // Emacs style mode select   -*- C++ -*- 
  2. //-----------------------------------------------------------------------------
  3. //
  4. // $Id:$
  5. //
  6. // Copyright (C) 1993-1996 by id Software, Inc.
  7. //
  8. // This source is available for distribution and/or modification
  9. // only under the terms of the DOOM Source Code License as
  10. // published by id Software. All rights reserved.
  11. //
  12. // The source is distributed in the hope that it will be useful,
  13. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
  15. // for more details.
  16. //
  17. // $Log:$
  18. //
  19. // DESCRIPTION:
  20. //    Refresh of things, i.e. objects represented by sprites.
  21. //
  22. //-----------------------------------------------------------------------------
  23.  
  24.  
  25. static const char
  26. rcsid[] = "$Id: r_things.c,v 1.5 1997/02/03 16:47:56 b1 Exp $";
  27.  
  28.  
  29. #include <stdio.h>
  30. #include <stdlib.h>
  31.  
  32.  
  33. #include "doomdef.h"
  34. #include "m_swap.h"
  35.  
  36. #include "i_system.h"
  37. #include "z_zone.h"
  38. #include "w_wad.h"
  39.  
  40. #include "r_local.h"
  41.  
  42. #include "doomstat.h"
  43.  
  44.  
  45.  
  46. #define MINZ                (FRACUNIT*4)
  47. //#define BASEYCENTER            100
  48. #define BASEYCENTER ((weirdaspect==1)?100:75)
  49.  
  50. //void R_DrawColumn (void);
  51. //void R_DrawFuzzColumn (void);
  52.  
  53.  
  54.  
  55. typedef struct
  56. {
  57.     int        x1;
  58.     int        x2;
  59.     
  60.     int        column;
  61.     int        topclip;
  62.     int        bottomclip;
  63.  
  64. } maskdraw_t;
  65.  
  66.  
  67.  
  68. //
  69. // Sprite rotation 0 is facing the viewer,
  70. //  rotation 1 is one angle turn CLOCKWISE around the axis.
  71. // This is not the same as the angle,
  72. //  which increases counter clockwise (protractor).
  73. // There was a lot of stuff grabbed wrong, so I changed it...
  74. //
  75. fixed_t        pspritescale;
  76. fixed_t        pspriteiscale;
  77. //fixed_t        pspritescale2;
  78. fixed_t        pspriteiscale2;
  79.  
  80. lighttable_t**    spritelights;
  81.  
  82. // constant arrays
  83. //  used for psprite clipping and initializing clipping
  84. //short        negonearray[SCREENWIDTH];
  85. //short        screenheightarray[SCREENWIDTH];
  86. short        *negonearray;
  87. short        *screenheightarray;
  88.  
  89.  
  90. //
  91. // INITIALIZATION FUNCTIONS
  92. //
  93.  
  94. // variables used to look up
  95. //  and range check thing_t sprites patches
  96. spritedef_t*    sprites;
  97. int        numsprites;
  98.  
  99. FAR spriteframe_t    sprtemp[29];
  100. int        maxframe;
  101. char*        spritename;
  102.  
  103.  
  104.  
  105.  
  106. //
  107. // R_InstallSpriteLump
  108. // Local function for R_InitSprites.
  109. //
  110. void
  111. R_InstallSpriteLump
  112. ( int        lump,
  113.   unsigned    frame,
  114.   unsigned    rotation,
  115.   boolean    flipped )
  116. {
  117.     int        r;
  118.     
  119.     if (frame >= 29 || rotation > 8)
  120.     I_Error("R_InstallSpriteLump: "
  121.         "Bad frame characters in lump %i", lump);
  122.     
  123.     if ((int)frame > maxframe)
  124.     maxframe = frame;
  125.         
  126.     if (rotation == 0)
  127.     {
  128.     // the lump should be used for all rotations
  129.     if (sprtemp[frame].rotate == false)
  130.         I_Error ("R_InitSprites: Sprite %s frame %c has "
  131.              "multip rot=0 lump", spritename, 'A'+frame);
  132.  
  133.     if (sprtemp[frame].rotate == true)
  134.         I_Error ("R_InitSprites: Sprite %s frame %c has rotations "
  135.              "and a rot=0 lump", spritename, 'A'+frame);
  136.             
  137.     sprtemp[frame].rotate = false;
  138.     for (r=0 ; r<8 ; r++)
  139.     {
  140.         sprtemp[frame].lump[r] = lump - firstspritelump;
  141.         sprtemp[frame].flip[r] = (byte)flipped;
  142.     }
  143.     return;
  144.     }
  145.     
  146.     // the lump is only used for one rotation
  147.     if (sprtemp[frame].rotate == false)
  148.     I_Error ("R_InitSprites: Sprite %s frame %c has rotations "
  149.          "and a rot=0 lump", spritename, 'A'+frame);
  150.         
  151.     sprtemp[frame].rotate = true;
  152.  
  153.     // make 0 based
  154.     rotation--;        
  155.     if (sprtemp[frame].lump[rotation] != -1)
  156.     I_Error ("R_InitSprites: Sprite %s : %c : %c "
  157.          "has two lumps mapped to it",
  158.          spritename, 'A'+frame, '1'+rotation);
  159.         
  160.     sprtemp[frame].lump[rotation] = lump - firstspritelump;
  161.     sprtemp[frame].flip[rotation] = (byte)flipped;
  162. }
  163.  
  164.  
  165.  
  166.  
  167. //
  168. // R_InitSpriteDefs
  169. // Pass a null terminated list of sprite names
  170. //  (4 chars exactly) to be used.
  171. // Builds the sprite rotation matrixes to account
  172. //  for horizontally flipped sprites.
  173. // Will report an error if the lumps are inconsistant. 
  174. // Only called at startup.
  175. //
  176. // Sprite lump names are 4 characters for the actor,
  177. //  a letter for the frame, and a number for the rotation.
  178. // A sprite that is flippable will have an additional
  179. //  letter/number appended.
  180. // The rotation character can be 0 to signify no rotations.
  181. //
  182. void R_InitSpriteDefs (char** namelist) 
  183.     char**    check;
  184.     int        i;
  185.     int        l;
  186.     int        intname;
  187.     int        frame;
  188.     int        rotation;
  189.     int        start;
  190.     int        end;
  191.     int        patched;
  192.         
  193.     // count the number of sprite names
  194.     check = namelist;
  195.     while (*check != NULL)
  196.     check++;
  197.  
  198.     numsprites = check-namelist;
  199.     
  200.     if (!numsprites)
  201.     return;
  202.         
  203.     sprites = Z_Malloc(numsprites *sizeof(*sprites), PU_STATIC, NULL);
  204.     
  205.     start = firstspritelump-1;
  206.     end = lastspritelump+1;
  207.     
  208.     // scan all the lump names for each of the names,
  209.     //  noting the highest frame letter.
  210.     // Just compare 4 characters as ints
  211.     for (i=0 ; i<numsprites ; i++)
  212.     {
  213.     spritename = namelist[i];
  214.     memset (sprtemp,-1, sizeof(sprtemp));
  215.         
  216.     maxframe = -1;
  217.     intname = *(int *)namelist[i];
  218.     
  219.     // scan the lumps,
  220.     //  filling in the frames for whatever is found
  221.     for (l=start+1 ; l<end ; l++)
  222.     {
  223.         if (*(int *)lumpinfo[l].name == intname)
  224.         {
  225.         frame = lumpinfo[l].name[4] - 'A';
  226.         rotation = lumpinfo[l].name[5] - '0';
  227.  
  228.         if (modifiedgame)
  229.             patched = W_GetNumForName (lumpinfo[l].name);
  230.         else
  231.             patched = l;
  232.  
  233.         R_InstallSpriteLump (patched, frame, rotation, false);
  234.  
  235.         if (lumpinfo[l].name[6])
  236.         {
  237.             frame = lumpinfo[l].name[6] - 'A';
  238.             rotation = lumpinfo[l].name[7] - '0';
  239.             R_InstallSpriteLump (l, frame, rotation, true);
  240.         }
  241.         }
  242.     }
  243.     
  244.     // check the frames that were found for completeness
  245.     if (maxframe == -1)
  246.     {
  247.         sprites[i].numframes = 0;
  248.         continue;
  249.     }
  250.         
  251.     maxframe++;
  252.     
  253.     for (frame = 0 ; frame < maxframe ; frame++)
  254.     {
  255.         switch ((int)sprtemp[frame].rotate)
  256.         {
  257.           case -1:
  258.         // no rotations were found for that frame at all
  259.         I_Error ("R_InitSprites: No patches found "
  260.              "for %s frame %c", namelist[i], frame+'A');
  261.         break;
  262.         
  263.           case 0:
  264.         // only the first rotation is needed
  265.         break;
  266.             
  267.           case 1:
  268.         // must have all 8 frames
  269.         for (rotation=0 ; rotation<8 ; rotation++)
  270.             if (sprtemp[frame].lump[rotation] == -1)
  271.             I_Error ("R_InitSprites: Sprite %s frame %c "
  272.                  "is missing rotations",
  273.                  namelist[i], frame+'A');
  274.         break;
  275.         }
  276.     }
  277.     
  278.     // allocate space for the frames present and copy sprtemp to it
  279.     sprites[i].numframes = maxframe;
  280.     sprites[i].spriteframes = 
  281.         Z_Malloc (maxframe * sizeof(spriteframe_t), PU_STATIC, NULL);
  282.     memcpy (sprites[i].spriteframes, sprtemp, maxframe*sizeof(spriteframe_t));
  283.     }
  284.  
  285. }
  286.  
  287.  
  288.  
  289.  
  290. //
  291. // GAME FUNCTIONS
  292. //
  293. FAR vissprite_t    vissprites[MAXVISSPRITES];
  294. vissprite_t*    vissprite_p;
  295. int        newvissprite;
  296.  
  297.  
  298.  
  299. //
  300. // R_InitSprites
  301. // Called at program start.
  302. //
  303. void R_InitSprites (char** namelist)
  304. {
  305.     int        i;
  306.     
  307.     for (i=0 ; i<SCREENWIDTH ; i++)
  308.     {
  309.     negonearray[i] = -1;
  310.     }
  311.     
  312.     R_InitSpriteDefs (namelist);
  313. }
  314.  
  315.  
  316.  
  317. #ifndef AMIGA
  318. //
  319. // R_ClearSprites
  320. // Called at frame start.
  321. //
  322. void R_ClearSprites (void)
  323. {
  324.     vissprite_p = vissprites;
  325. }
  326. #endif
  327.  
  328.  
  329. #ifdef AMIGA
  330. extern vissprite_t* R_NewVisSprite (void);
  331. #else
  332. //
  333. // R_NewVisSprite
  334. //
  335. vissprite_t    overflowsprite;
  336.  
  337. vissprite_t* R_NewVisSprite (void)
  338. {
  339.     if (vissprite_p == &vissprites[MAXVISSPRITES])
  340.     return &overflowsprite;
  341.     
  342.     vissprite_p++;
  343.     return vissprite_p-1;
  344. }
  345. #endif
  346.  
  347.  
  348.  
  349. //
  350. // R_DrawMaskedColumn
  351. // Used for sprites and masked mid textures.
  352. // Masked means: partly transparent, i.e. stored
  353. //  in posts/runs of opaque pixels.
  354. //
  355. short*        mfloorclip;
  356. short*        mceilingclip;
  357.  
  358. fixed_t        spryscale;
  359. fixed_t        sprtopscreen;
  360.  
  361. #ifndef AMIGA
  362. void R_DrawMaskedColumn (column_t* column)
  363. {
  364.     int        topscreen;
  365.     int     bottomscreen;
  366.     fixed_t    basetexturemid;
  367.     
  368.     basetexturemid = dc_texturemid;
  369.     
  370.     for ( ; column->topdelta != 0xff ; ) 
  371.     {
  372.     // calculate unclipped screen coordinates
  373.     //  for post
  374.     topscreen = sprtopscreen + spryscale*column->topdelta;
  375.     bottomscreen = topscreen + spryscale*column->length;
  376.  
  377.     dc_yl = (topscreen+FRACUNIT-1)>>FRACBITS;
  378.     dc_yh = (bottomscreen-1)>>FRACBITS;
  379.         
  380.     if (dc_yh >= mfloorclip[dc_x])
  381.         dc_yh = mfloorclip[dc_x]-1;
  382.     if (dc_yl <= mceilingclip[dc_x])
  383.         dc_yl = mceilingclip[dc_x]+1;
  384.  
  385.     if (dc_yl <= dc_yh)
  386.     {
  387.         dc_source = (byte *)column + 3;
  388.         dc_texturemid = basetexturemid - (column->topdelta<<FRACBITS);
  389.         // dc_source = (byte *)column + 3 - column->topdelta;
  390.  
  391.         // Drawn by either R_DrawColumn
  392.         //  or (SHADOW) R_DrawFuzzColumn.
  393.         colfunc ();    
  394.     }
  395.     column = (column_t *)(  (byte *)column + column->length + 4);
  396.     }
  397.     
  398.     dc_texturemid = basetexturemid;
  399. }
  400. #endif
  401.  
  402.  
  403.  
  404. #ifdef AMIGA
  405. extern void R_DrawVisSprite (vissprite_t *vis);
  406. #else
  407. //
  408. // R_DrawVisSprite
  409. //  mfloorclip and mceilingclip should also be set.
  410. //
  411. void
  412. R_DrawVisSprite
  413. ( vissprite_t*        vis,
  414.   int            x1,
  415.   int            x2 )
  416. {
  417.     column_t*        column;
  418.     int            texturecolumn;
  419.     fixed_t        frac;
  420.     patch_t*        patch;
  421.     
  422. //#ifdef AMIGA
  423. //    int            type = TYPE_NORMAL;
  424. //#endif
  425.  
  426.     
  427.     patch = W_CacheLumpNum (vis->patch+firstspritelump, PU_CACHE);
  428.  
  429.     dc_colormap = vis->colormap;
  430.     
  431.     if (!dc_colormap)
  432.     {
  433. //#ifndef AMIGA
  434.     // NULL colormap = shadow draw
  435.     colfunc = fuzzcolfunc;
  436. //#else
  437. //        type = TYPE_FUZZ;
  438. //#endif
  439.     }
  440.     else if (vis->mobjflags & MF_TRANSLATION)
  441.     {
  442. //#ifndef AMIGA
  443.     colfunc = transcolfunc;
  444. //#else
  445. //        type = TYPE_TRANSL;
  446. //#endif
  447.     dc_translation = translationtables - 256 +
  448.         ( (vis->mobjflags & MF_TRANSLATION) >> (MF_TRANSSHIFT-8) );
  449.     }
  450.     
  451.     dc_iscale = iabs(vis->xiscale)>>detailshift;
  452.     dc_texturemid = vis->texturemid;
  453.     frac = vis->startfrac;
  454.     spryscale = vis->scale;
  455.     sprtopscreen = centeryfrac - FixedMul(dc_texturemid,spryscale);
  456.     
  457.     for (dc_x=vis->x1 ; dc_x<=vis->x2 ; dc_x++, frac += vis->xiscale)
  458.     {
  459.     texturecolumn = frac>>FRACBITS;
  460. #ifdef RANGECHECK
  461.     if (texturecolumn < 0 || texturecolumn >= SWAPSHORT(patch->width))
  462.         I_Error ("R_DrawSpriteRange: bad texturecolumn");
  463. #endif
  464.     column = (column_t *) ((byte *)patch +
  465.                    SWAPLONG(patch->columnofs[texturecolumn]));
  466.  
  467. //#ifndef AMIGA
  468.      R_DrawMaskedColumn (column);
  469. //#else
  470. //    R_DrawMaskedColumnAmi (column, type);
  471. //#endif
  472.     }
  473.  
  474.     colfunc = basecolfunc;
  475. }
  476. #endif
  477.  
  478.  
  479.  
  480. //
  481. // R_ProjectSprite
  482. // Generates a vissprite for a thing
  483. //  if it might be visible.
  484. //
  485. void R_ProjectSprite (mobj_t* thing)
  486. {
  487.     fixed_t        tr_x;
  488.     fixed_t        tr_y;
  489.     
  490.     fixed_t        gxt;
  491.     fixed_t        gyt;
  492.     
  493.     fixed_t        tx;
  494.     fixed_t        tz;
  495.  
  496.     fixed_t        xscale;
  497.     
  498.     int            x1;
  499.     int            x2;
  500.  
  501.     spritedef_t*    sprdef;
  502.     spriteframe_t*    sprframe;
  503.     int            lump;
  504.     
  505.     unsigned        rot;
  506.     boolean        flip;
  507.     
  508.     int            index;
  509.  
  510.     vissprite_t*    vis;
  511.     
  512.     angle_t        ang;
  513.     fixed_t        iscale;
  514.     
  515.     // transform the origin point
  516.     tr_x = thing->x - viewx;
  517.     tr_y = thing->y - viewy;
  518.     
  519.     gxt = FixedMul(tr_x,viewcos); 
  520.     gyt = -FixedMul(tr_y,viewsin);
  521.     
  522.     tz = gxt-gyt; 
  523.  
  524.     // thing is behind view plane?
  525.     if (tz < MINZ)
  526.     return;
  527.     
  528.     xscale = FixedDiv(projection, tz);
  529.     
  530.     gxt = -FixedMul(tr_x,viewsin); 
  531.     gyt = FixedMul(tr_y,viewcos); 
  532.     tx = -(gyt+gxt); 
  533.  
  534.     // too far off the side?
  535.     if (iabs(tx)>(tz<<2))
  536.     return;
  537.     
  538.     // decide which patch to use for sprite relative to player
  539. #ifdef RANGECHECK
  540.     if ((unsigned)thing->sprite >= numsprites)
  541.     I_Error ("R_ProjectSprite: invalid sprite number %i ",
  542.          thing->sprite);
  543. #endif
  544.     sprdef = &sprites[thing->sprite];
  545. #ifdef RANGECHECK
  546.     if ( (thing->frame&FF_FRAMEMASK) >= sprdef->numframes )
  547.     I_Error ("R_ProjectSprite: invalid sprite frame %i : %i ",
  548.          thing->sprite, thing->frame);
  549. #endif
  550.     sprframe = &sprdef->spriteframes[ thing->frame & FF_FRAMEMASK];
  551.  
  552.     if (sprframe->rotate)
  553.     {
  554.     // choose a different rotation based on player view
  555.     ang = R_PointToAngle (thing->x, thing->y);
  556.     rot = (ang-thing->angle+(unsigned)(ANG45/2)*9)>>29;
  557.     lump = sprframe->lump[rot];
  558.     flip = (boolean)sprframe->flip[rot];
  559.     }
  560.     else
  561.     {
  562.     // use single rotation for all views
  563.     lump = sprframe->lump[0];
  564.     flip = (boolean)sprframe->flip[0];
  565.     }
  566.     
  567.     // calculate edges of the shape
  568.     tx -= spriteoffset[lump];    
  569.     x1 = (centerxfrac + FixedMul (tx,xscale) ) >>FRACBITS;
  570.  
  571.     // off the right side?
  572.     if (x1 > viewwidth)
  573.     return;
  574.     
  575.     tx +=  spritewidth[lump];
  576.     x2 = ((centerxfrac + FixedMul (tx,xscale) ) >>FRACBITS) - 1;
  577.  
  578.     // off the left side
  579.     if (x2 < 0)
  580.     return;
  581.     
  582.     // store information in a vissprite
  583.     vis = R_NewVisSprite ();
  584.     vis->mobjflags = thing->flags;
  585.     vis->scale = xscale<<detailshift;
  586.     vis->gx = thing->x;
  587.     vis->gy = thing->y;
  588.     vis->gz = thing->z;
  589.     vis->gzt = thing->z + spritetopoffset[lump];
  590.     vis->texturemid = vis->gzt - viewz;
  591.     vis->x1 = x1 < 0 ? 0 : x1;
  592.     vis->x2 = x2 >= viewwidth ? viewwidth-1 : x2;    
  593.     iscale = FixedDiv (FRACUNIT, xscale);
  594.  
  595.     if (flip)
  596.     {
  597.     vis->startfrac = spritewidth[lump]-1;
  598.     vis->xiscale = -iscale;
  599.     }
  600.     else
  601.     {
  602.     vis->startfrac = 0;
  603.     vis->xiscale = iscale;
  604.     }
  605.  
  606.     if (vis->x1 > x1)
  607.     vis->startfrac += vis->xiscale*(vis->x1-x1);
  608.     vis->patch = lump;
  609.     
  610.     // get light level
  611.     if (thing->flags & MF_SHADOW)
  612.     {
  613.     // shadow draw
  614.     vis->colormap = NULL;
  615.     }
  616.     else if (fixedcolormap)
  617.     {
  618.     // fixed map
  619.     vis->colormap = fixedcolormap;
  620.     }
  621.     else if (thing->frame & FF_FULLBRIGHT)
  622.     {
  623.     // full bright
  624.     vis->colormap = colormaps;
  625.     }
  626.     
  627.     else
  628.     {
  629.     // diminished light
  630.     index = xscale>>(LIGHTSCALESHIFT-detailshift);
  631.  
  632.     if (index >= MAXLIGHTSCALE) 
  633.         index = MAXLIGHTSCALE-1;
  634.  
  635.     vis->colormap = spritelights[index];
  636.     }    
  637. }
  638.  
  639.  
  640.  
  641.  
  642. #ifndef AMIGA
  643. //
  644. // R_AddSprites
  645. // During BSP traversal, this adds sprites by sector.
  646. //
  647. void R_AddSprites (sector_t* sec)
  648. {
  649.     mobj_t*        thing;
  650.     int            lightnum;
  651.  
  652.     // BSP is traversed by subsector.
  653.     // A sector might have been split into several
  654.     //  subsectors during BSP building.
  655.     // Thus we check whether its already added.
  656.     if (sec->validcount == validcount)
  657.     return;        
  658.  
  659.     // Well, now it will be done.
  660.     sec->validcount = validcount;
  661.     
  662.     lightnum = (sec->lightlevel >> LIGHTSEGSHIFT)+extralight;
  663.  
  664.     if (lightnum < 0)        
  665.     spritelights = scalelight[0];
  666.     else if (lightnum >= LIGHTLEVELS)
  667.     spritelights = scalelight[LIGHTLEVELS-1];
  668.     else
  669.     spritelights = scalelight[lightnum];
  670.  
  671.     // Handle all things in sector.
  672.     for (thing = sec->thinglist ; thing ; thing = thing->snext)
  673.     R_ProjectSprite (thing);
  674. }
  675. #endif
  676.  
  677.  
  678. //
  679. // R_DrawPSprite
  680. //
  681. void R_DrawPSprite (pspdef_t* psp)
  682. {
  683.     fixed_t        tx;
  684.     int            x1;
  685.     int            x2;
  686.     spritedef_t*    sprdef;
  687.     spriteframe_t*    sprframe;
  688.     int            lump;
  689.     boolean        flip;
  690.     vissprite_t*    vis;
  691.     vissprite_t        avis;
  692.     
  693.     // decide which patch to use
  694. #ifdef RANGECHECK
  695.     if ( (unsigned)psp->state->sprite >= numsprites)
  696.     I_Error ("R_ProjectSprite: invalid sprite number %i ",
  697.          psp->state->sprite);
  698. #endif
  699.     sprdef = &sprites[psp->state->sprite];
  700. #ifdef RANGECHECK
  701.     if ( (psp->state->frame & FF_FRAMEMASK)  >= sprdef->numframes)
  702.     I_Error ("R_ProjectSprite: invalid sprite frame %i : %i ",
  703.          psp->state->sprite, psp->state->frame);
  704. #endif
  705.     sprframe = &sprdef->spriteframes[ psp->state->frame & FF_FRAMEMASK ];
  706.  
  707.     lump = sprframe->lump[0];
  708.     flip = (boolean)sprframe->flip[0];
  709.     
  710.     // calculate edges of the shape
  711.     tx = psp->sx-160*FRACUNIT;
  712.     
  713.     tx -= spriteoffset[lump];    
  714.     x1 = (centerxfrac + FixedMul (tx,pspritescale) ) >>FRACBITS;
  715.  
  716.     // off the right side
  717.     if (x1 > viewwidth)
  718.     return;        
  719.  
  720.     tx +=  spritewidth[lump];
  721.     x2 = ((centerxfrac + FixedMul (tx, pspritescale) ) >>FRACBITS) - 1;
  722.  
  723.     // off the left side
  724.     if (x2 < 0)
  725.     return;
  726.     
  727.     // store information in a vissprite
  728.     vis = &avis;
  729.     vis->mobjflags = 0;
  730.     vis->texturemid = (BASEYCENTER<<FRACBITS)+FRACUNIT/2-(psp->sy-spritetopoffset[lump]);
  731.     vis->x1 = x1 < 0 ? 0 : x1;
  732.     vis->x2 = x2 >= viewwidth ? viewwidth-1 : x2;    
  733.     vis->scale = pspritescale<<detailshift;
  734.     
  735.     if (flip)
  736.     {
  737.     vis->xiscale = -pspriteiscale;
  738.     vis->startfrac = spritewidth[lump]-1;
  739.     }
  740.     else
  741.     {
  742.     vis->xiscale = pspriteiscale;
  743.     vis->startfrac = 0;
  744.     }
  745.     
  746.     if (vis->x1 > x1)
  747.     vis->startfrac += vis->xiscale*(vis->x1-x1);
  748.  
  749.     vis->patch = lump;
  750.  
  751.     if (viewplayer->powers[pw_invisibility] > 4*32
  752.     || viewplayer->powers[pw_invisibility] & 8)
  753.     {
  754.     // shadow draw
  755.     vis->colormap = NULL;
  756.     }
  757.     else if (fixedcolormap)
  758.     {
  759.     // fixed color
  760.     vis->colormap = fixedcolormap;
  761.     }
  762.     else if (psp->state->frame & FF_FULLBRIGHT)
  763.     {
  764.     // full bright
  765.     vis->colormap = colormaps;
  766.     }
  767.     else
  768.     {
  769.     // local light
  770.     vis->colormap = spritelights[MAXLIGHTSCALE-1];
  771.     }
  772.     
  773. #ifdef AMIGA
  774.     R_DrawVisSprite (vis);
  775. #else
  776.     R_DrawVisSprite (vis, vis->x1, vis->x2);
  777. #endif
  778. }
  779.  
  780.  
  781.  
  782. //
  783. // R_DrawPlayerSprites
  784. //
  785. void R_DrawPlayerSprites (void)
  786. {
  787.     int        i;
  788.     int        lightnum;
  789.     pspdef_t*    psp;
  790.     
  791.     // get light level
  792.     lightnum =
  793.     (viewplayer->mo->subsector->sector->lightlevel >> LIGHTSEGSHIFT) 
  794.     +extralight;
  795.  
  796.     if (lightnum < 0)        
  797.     spritelights = scalelight[0];
  798.     else if (lightnum >= LIGHTLEVELS)
  799.     spritelights = scalelight[LIGHTLEVELS-1];
  800.     else
  801.     spritelights = scalelight[lightnum];
  802.     
  803.     // clip to screen bounds
  804.     mfloorclip = screenheightarray;
  805.     mceilingclip = negonearray;
  806.     
  807.     // add all active psprites
  808.     for (i=0, psp=viewplayer->psprites;
  809.      i<NUMPSPRITES;
  810.      i++,psp++)
  811.     {
  812.     if (psp->state)
  813.         R_DrawPSprite (psp);
  814.     }
  815. }
  816.  
  817.  
  818. vissprite_t    vsprsortedhead;
  819.  
  820. #ifndef AMIGA
  821. //
  822. // R_SortVisSprites
  823. //
  824. void R_SortVisSprites (void)
  825. {
  826.     int            i;
  827.     int            count;
  828.     vissprite_t*    ds;
  829.     vissprite_t*    best;
  830.     vissprite_t        unsorted;
  831.     fixed_t        bestscale;
  832.  
  833.     count = vissprite_p - vissprites;
  834.     
  835.     unsorted.next = unsorted.prev = &unsorted;
  836.  
  837.     if (!count)
  838.     return;
  839.         
  840.     for (ds=vissprites ; ds<vissprite_p ; ds++)
  841.     {
  842.     ds->next = ds+1;
  843.     ds->prev = ds-1;
  844.     }
  845.     
  846.     vissprites[0].prev = &unsorted;
  847.     unsorted.next = &vissprites[0];
  848.     (vissprite_p-1)->next = &unsorted;
  849.     unsorted.prev = vissprite_p-1;
  850.     
  851.     // pull the vissprites out by scale
  852.     //best = 0;        // shut up the compiler warning
  853.     vsprsortedhead.next = vsprsortedhead.prev = &vsprsortedhead;
  854.     for (i=0 ; i<count ; i++)
  855.     {
  856.     bestscale = MAXINT;
  857.     for (ds=unsorted.next ; ds!= &unsorted ; ds=ds->next)
  858.     {
  859.         if (ds->scale < bestscale)
  860.         {
  861.         bestscale = ds->scale;
  862.         best = ds;
  863.         }
  864.     }
  865.     best->next->prev = best->prev;
  866.     best->prev->next = best->next;
  867.     best->next = &vsprsortedhead;
  868.     best->prev = vsprsortedhead.prev;
  869.     vsprsortedhead.prev->next = best;
  870.     vsprsortedhead.prev = best;
  871.     }
  872. }
  873. #endif
  874.  
  875.  
  876.  
  877. #ifndef AMIGA
  878. //
  879. // R_DrawSprite
  880. //
  881. void R_DrawSprite (vissprite_t* spr)
  882. {
  883.     drawseg_t*        ds;
  884. //    short        clipbot[SCREENWIDTH];
  885. //    short        cliptop[SCREENWIDTH];
  886.     static short    clipbot[MAXSCREENWIDTH];
  887.     static short    cliptop[MAXSCREENWIDTH];
  888.     int            x;
  889.     int            r1;
  890.     int            r2;
  891.     fixed_t        scale;
  892.     fixed_t        lowscale;
  893.     int            silhouette;
  894.  
  895. //    clipbot = I_malloc (SCREENWIDTH * sizeof(short));
  896. //    cliptop = I_malloc (SCREENWIDTH * sizeof(short));
  897.  
  898.     for (x = spr->x1 ; x<=spr->x2 ; x++)
  899.     clipbot[x] = cliptop[x] = -2;
  900.     
  901.     // Scan drawsegs from end to start for obscuring segs.
  902.     // The first drawseg that has a greater scale
  903.     //  is the clip seg.
  904.     for (ds=ds_p-1 ; ds >= drawsegs ; ds--)
  905.     {
  906.     // determine if the drawseg obscures the sprite
  907.     if (ds->x1 > spr->x2
  908.         || ds->x2 < spr->x1
  909.         || (!ds->silhouette
  910.         && !ds->maskedtexturecol) )
  911.     {
  912.         // does not cover sprite
  913.         continue;
  914.     }
  915.             
  916.     r1 = ds->x1 < spr->x1 ? spr->x1 : ds->x1;
  917.     r2 = ds->x2 > spr->x2 ? spr->x2 : ds->x2;
  918.  
  919.     if (ds->scale1 > ds->scale2)
  920.     {
  921.         lowscale = ds->scale2;
  922.         scale = ds->scale1;
  923.     }
  924.     else
  925.     {
  926.         lowscale = ds->scale1;
  927.         scale = ds->scale2;
  928.     }
  929.         
  930.     if (scale < spr->scale
  931.         || ( lowscale < spr->scale
  932.          && !R_PointOnSegSide (spr->gx, spr->gy, ds->curline) ) )
  933.     {
  934.         // masked mid texture?
  935.         if (ds->maskedtexturecol)    
  936.         R_RenderMaskedSegRange (ds, r1, r2);
  937.         // seg is behind sprite
  938.         continue;            
  939.     }
  940.  
  941.     
  942.     // clip this piece of the sprite
  943.     silhouette = ds->silhouette;
  944.     
  945.     if (spr->gz >= ds->bsilheight)
  946.         silhouette &= ~SIL_BOTTOM;
  947.  
  948.     if (spr->gzt <= ds->tsilheight)
  949.         silhouette &= ~SIL_TOP;
  950.             
  951.     if (silhouette == 1)
  952.     {
  953.         // bottom sil
  954.         for (x=r1 ; x<=r2 ; x++)
  955.         if (clipbot[x] == -2)
  956.             clipbot[x] = ds->sprbottomclip[x];
  957.     }
  958.     else if (silhouette == 2)
  959.     {
  960.         // top sil
  961.         for (x=r1 ; x<=r2 ; x++)
  962.         if (cliptop[x] == -2)
  963.             cliptop[x] = ds->sprtopclip[x];
  964.     }
  965.     else if (silhouette == 3)
  966.     {
  967.         // both
  968.         for (x=r1 ; x<=r2 ; x++)
  969.         {
  970.         if (clipbot[x] == -2)
  971.             clipbot[x] = ds->sprbottomclip[x];
  972.         if (cliptop[x] == -2)
  973.             cliptop[x] = ds->sprtopclip[x];
  974.         }
  975.     }
  976.         
  977.     }
  978.     
  979.     // all clipping has been performed, so draw the sprite
  980.  
  981.     // check for unclipped columns
  982.     for (x = spr->x1 ; x<=spr->x2 ; x++)
  983.     {
  984.     if (clipbot[x] == -2)        
  985.         clipbot[x] = viewheight;
  986.  
  987.     if (cliptop[x] == -2)
  988.         cliptop[x] = -1;
  989.     }
  990.         
  991.     mfloorclip = clipbot;
  992.     mceilingclip = cliptop;
  993.     R_DrawVisSprite (spr, spr->x1, spr->x2);
  994.  
  995. //    free (clipbot);
  996. //    free (cliptop);
  997. }
  998. #endif
  999.  
  1000.  
  1001.  
  1002.  
  1003. #ifndef AMIGA
  1004. //
  1005. // R_DrawMasked
  1006. //
  1007. void R_DrawMasked (void)
  1008. {
  1009.     vissprite_t*    spr;
  1010.     drawseg_t*        ds;
  1011.     
  1012.     R_SortVisSprites ();
  1013.  
  1014.     if (vissprite_p > vissprites)
  1015.     {
  1016.     // draw all vissprites back to front
  1017.     for (spr = vsprsortedhead.next ;
  1018.          spr != &vsprsortedhead ;
  1019.          spr=spr->next)
  1020.     {
  1021.         
  1022.         R_DrawSprite (spr);
  1023.     }
  1024.     }
  1025.     
  1026.     // render any remaining masked mid textures
  1027.     for (ds=ds_p-1 ; ds >= drawsegs ; ds--)
  1028.     if (ds->maskedtexturecol)
  1029.         R_RenderMaskedSegRange (ds, ds->x1, ds->x2);
  1030.     
  1031.     // draw the psprites on top of everything
  1032.     //  but does not draw on side views
  1033.     if (!viewangleoffset)        
  1034.     R_DrawPlayerSprites ();
  1035. }
  1036. #endif
  1037.  
  1038.